'use strict';

const uidObj = require('uni-id');
const uidPay = require('uni-pay');

const uniConfig = require('uni-config-center');
const uidConfig = uniConfig({
	pluginId: 'uni-id'
});

const {
	Controller
} = require('uni-cloud-router');
const dbcmd = uniCloud.database().command;

module.exports = class PayController extends Controller {
	
	// 支付下单
	async order() {
		let response = {
			code: 1,
		};

		const start = new Date().getTime();
		const {
			code,
			pay_openid, // 付款人 openid
			pay_way,
			pay_original,
			pay_trade_type,
			money,
			title,
			order_id
		} = this.ctx.data;
		
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		if (money <= 0) {
			response.msg = '支付金额需大于0';
			return response;
		}
		
		// 配置项
		const config = this.service.utils.getConfig();
		
		// 根据支付方式获取对应 code 的 openid 
		// 根据支付方式获取对应的下单数据
		let openid = pay_openid || '';
		// 同步微信发货
		let wx_delivery = 0;
		
		const fee = money * 100;
		const paytitle = `${config.appname}-${title}`;
		let payid = order_id || ('usemall-' + new Date().getTime() + (Math.round(Math.random() * 1000000) + '').padStart(6, '0'));
		let payres = '';
		let paypreid = '';
		let payOrderInfo = {};

		switch (pay_way) {
			case '微信支付':
				// 初始化微信支付
				let wxpayConfig;
				if (pay_trade_type == 'APP') {
					// APP 微信支付
					wxpayConfig = uidConfig.config('app.wxpay');
				} else if (pay_trade_type == 'H5WX') {
					// 微信公众号 微信支付
					wxpayConfig = uidConfig.config('h5-weixin.pay');
				} else {
					// 微信小程序 微信支付
					wxpayConfig = uidConfig.config('mp-weixin.pay');
				}
				const uniWxpayIns = uidPay.initWeixin(wxpayConfig);
				
				let wxpayOrderInfo = {};
				switch (pay_trade_type) {
					case 'APP': // APP
					case 'MWEB': // H5 微信外部浏览器
					case 'H5WX': // H5 微信公众号（内部浏览器）
					case 'NATIVE': // 二维码
						// 二维码有效期 剩余时间
						let time_remaining = 60 * 60 * 1.5;
						// 剩余时间
						wxpayOrderInfo.time_remaining = time_remaining;
						
						let preOrderInfo = {};
						// 支付回调地址
						let notifyUrl;
						if (pay_trade_type == 'APP') {
							// APP 
							notifyUrl = uidConfig.config('app.notify-recharge-wxpay-url');
						} else if (pay_trade_type == 'H5WX') {
							// 微信公众号 
							notifyUrl = uidConfig.config('h5-weixin.notify-recharge-url');
							// 获取用户微信公众号对应的 openid
							preOrderInfo.openid = openid;
							preOrderInfo.tradeType = 'JSAPI';
						} else {
							// 微信小程序 
							notifyUrl = uidConfig.config('mp-weixin.notify-recharge-url');
						}
						
						// 获取下单数据
						wxpayOrderInfo = await uniWxpayIns.getOrderInfo({
							body: paytitle,
							outTradeNo: payid,
							totalFee: fee,
							tradeType: pay_trade_type,
							notifyUrl: notifyUrl,
							spbillCreateIp: this.ctx.context.CLIENTIP,
							...preOrderInfo,
						});
						
						uniCloud.logger.info(wxpayOrderInfo);
						break;
					default:	// 小程序微信支付
						const wxres = await uidObj.code2SessionWeixin(code);
						if (!(wxres && wxres.code == 0)) {
							this.throw(wxres.message || '请重新授权登录后支付');
						}

						// 用户 openid
						openid = wxres.openid;
						
						const configRes = await this.db.collection('usemall-wallet-parameter').get();
						const [config = {}] = configRes.data;
						// 微信小程序支付统一需要同步发货
						wx_delivery = config.syncWx ? 1 : 0;

						wxpayOrderInfo = await uniWxpayIns.getOrderInfo({
							openid: openid,
							body: paytitle,
							outTradeNo: payid,
							totalFee: fee,
							notifyUrl: uidConfig.config('mp-weixin.notify-recharge-url')
						});
						break;
				}
				// 下单支付参数
				payOrderInfo = wxpayOrderInfo;

				paypreid = wxpayOrderInfo.prepayId;
				payres = JSON.stringify(wxpayOrderInfo);
				break;
			case '支付宝':
				const fs = require('fs');
				const path = require('path');
				
				// 初始化支付
				let alipayConfig = uidConfig.config('mp-alipay.pay');
				if (pay_trade_type == 'APP') {
					alipayConfig = uidConfig.config('app.alipay');
				}
				
				// 初始化支付宝支付
				const uniAlipayIns = uidPay.initAlipay(alipayConfig);
				let alipayOrderInfo = {};
				let notifyUrl = uidConfig.config('mp-alipay.notify-recharge-url');
				if (pay_trade_type == 'APP') {
					notifyUrl = uidConfig.config('app.notify-recharge-alipay-url');
				}
				
				switch (pay_trade_type){
					case 'APP':
						// 获取支付参数，注意支付宝返回的是 trade_no 字符串
						alipayOrderInfo = await uniAlipayIns.getOrderInfo({
							openid: openid,
							subject: paytitle,
							outTradeNo: payid,
							totalFee: fee,
							notifyUrl: notifyUrl
						});
						
						payOrderInfo = {
							orderInfo: alipayOrderInfo
						};
						break;
					default:	// 小程序支付宝支付
						const alires = await uidObj.code2SessionAlipay(code);
						if (!(alires && alires.code == 0)) {
							this.throw(alires.message || '请重新授权登录后支付');
						}
						// 用户openid
						openid = alires.openid;
						// 获取支付参数，注意支付宝返回的是 trade_no 字符串
						alipayOrderInfo = await uniAlipayIns.getOrderInfo({
							openid: openid,
							subject: paytitle,
							outTradeNo: payid,
							totalFee: fee,
							notifyUrl: notifyUrl
						});
						
						// 下单支付参数
						payOrderInfo = {
							trade_no: alipayOrderInfo
						};
						break;
				}
				
				uniCloud.logger.info("alipayOrderInfo: ", alipayOrderInfo);
				
				paypreid = alipayOrderInfo.prepayId;
				payres = JSON.stringify(alipayOrderInfo);
				break;
			case '百度钱包':
				break;
			case 'QQ钱包':
				break;
			case '头条支付':
				break;
			case '余额支付':
				break;
			default:
				break;
		}
		
		await this.db.collection('usemall-member-pay').doc(payid).set({
			pay_id: payid,
			pay_money: money,
			pay_openid: openid,
			pay_title: title,
			pay_way: pay_way,
			pay_original: pay_original,
			pay_trade_type: pay_trade_type,
			pay_preid: paypreid,
			pay_res: payres,
			pay_state: '待付款',
			wx_delivery: wx_delivery,
			wx_delivery_sync: 0,
			version: 1,
			is_delete: 0,
			create_uid: uid,
			create_time: new Date().getTime()
		});

		// 返回下单数据
		payOrderInfo.pay_id = payid;
		response.datas = payOrderInfo;

		const end = new Date().getTime();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}

	// 支付状态查询
	async state() {
		let response = {
			code: 1,
			msg: '支付状态查询失败'
		};

		const {
			pay_id
		} = this.ctx.data;

		if (!pay_id) {
			response.msg = '交易号不存在';
			return response;
		}

		// 查询订单支付状态
		const payRes = await this.db.collection('usemall-member-pay').where({
			pay_id
		}).get();
		if (!payRes || payRes.data.length !== 1) {
			response.msg = '支付单不存在';
			return response;
		}

		const payObj = payRes.data[0];
		if (payObj.pay_state == '已付款') {
			response.code = 0;
			response.datas = {
				pay_state: payObj.pay_state,
				pay_id: payObj.pay_id
			};
			return response;
		}

		switch (payObj.pay_way) {
			case '微信支付':
				const uniWxpayIns = uidPay.initWeixin(uidConfig.config('mp-weixin.pay'));
				const uniWxpayRes = await uniWxpayIns.orderQuery({
					outTradeNo: pay_id,
				});

				response.code = 0;
				response.datas = {
					pay_state: payObj.pay_state,
					pay_id: payObj.pay_id,
					trade_state: uniWxpayRes.tradeState
				};
				return response;
			case '支付宝':
				const uniAlipayIns = uidPay.initWeixin(uidConfig.config('mp-alipay.pay'));
				const uniAlipayRes = await uniAlipayIns.orderQuery({
					outTradeNo: pay_id,
				});

				response.code = 0;
				response.datas = {
					pay_state: payObj.pay_state,
					pay_id: payObj.pay_id,
					trade_state: uniAlipayRes.tradeState
				};
				return response;
		}

		return response;
	}
	
	// 支付成功
	async success() {
		let response = {
			code: 1,
		};
		
		const start = new Date().getTime();
		const nowdate = start;
		const {
			pid
		} = this.ctx.data;
		
		let uid = '';
		if (this.ctx.event.uniIdToken) {
			// 已登录，获取当前登录 uid
			const userRes = await uidObj.checkToken(this.ctx.event.uniIdToken);
			if (userRes.code == 0) {
				uid = userRes.uid;
			}
		}
		if (!uid) {
			response.msg = '当前未登录'
			return response;
		}
		
		if (!pid) {
			response.msg = `订单不存在`;
			return response;
		}
		
		const orderRes = await this.db.collection('usemall-member-pay').doc(pid).get();
		const [orderPay] = orderRes.data;
		if (!orderPay) {
			response.msg = `订单[${pid}]不存在`;
			return response;
		}
		
		const payLogRes = await this.db.collection('usemall-member-money-log').doc(pid).get();
		const [payLog] = payLogRes.data;
		if (!payLog) {
			await this.db.collection('usemall-member-money-log').doc(pid).set({
				user_uid: uid,
				order_id: pid,
				express_cost: 0,
				money: orderPay.pay_money,
				money_fmt: '+' + orderPay.pay_money,
				source: orderPay.pay_way,
				state: '待核实',
				type: '充值',
				remark: `通过${orderPay.pay_way}充值+${orderPay.pay_money}`,
				ip: '',
				is_delete: 0,
				create_uid: uid,
				create_time: nowdate
			});
		}
		
		const end = new Date().getTime();
		console.log(`耗时：${end - start}ms`);
		response.code = 0;
		response.duration = `耗时：${end - start}ms`;
		return response;
	}
}
